package com.greenant.store.view;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.BitmapDrawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.greenant.store.R;

public class MSpinner extends RelativeLayout implements OnClickListener, OnFocusChangeListener{
    private Context mContext;
    
    private View mContentView;
    private TextView mTitleTV;
    private ImageView mArrowIV;
    
    private boolean mEnabled = true;
    private boolean isDisplayFirstLabel = false;
    private boolean isDisplayItemInTitle = true;
    
    private String mSelectedText;
    private String mHintStr = "";
    
    private MSpinnerBean mSelectedMSpinnerBean;
    
    public enum MSpinnerState{
        STATE_OPEN,
        STATE_CLOSE
    }
    
    private MSpinnerState mMSpinnerState = MSpinnerState.STATE_CLOSE;
    
    private MSpinnerPopupWindow mMSpinnerPopupWindow;
    
    private OnMSpinnerItemClickListener mOnMSpinnerItemClickListener;
    public void setOnMSpinnerItemClickListener(OnMSpinnerItemClickListener listener){
        mOnMSpinnerItemClickListener = listener;
    }
    
    public interface OnMSpinnerItemClickListener{
        public void onMSpinnerItemClick(MSpinner mspinner, int position, MSpinnerBean bean);
    }
    
    public MSpinner(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        this.setOnClickListener(this);
        this.setFocusable(true);
        this.setOnFocusChangeListener(this);
        
        initView();
    }
    
    private void initView(){
        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mContentView = inflater.inflate(R.layout.mspinner, this);
        
        mTitleTV = (TextView)mContentView.findViewById(R.id.mspinner_title);
        mArrowIV = (ImageView)mContentView.findViewById(R.id.mspinner_arrow);
        
        mMSpinnerPopupWindow = new MSpinnerPopupWindow();
    }
    
    public void setText(String text){
        if(TextUtils.isEmpty(text)){
        	mTitleTV.setText(mHintStr);
            return;
        }
        mTitleTV.setText(text);
    }
    
    public String getText(){
        return mSelectedText;
    }
    
    public void setArrowIcon(int arrowRes) {
    	mArrowIV.setImageResource(arrowRes);
    }
    
    public void setTitleTextColor(int color) {
    	mTitleTV.setTextColor(color);
    }
    
    public void setTitleGravity(int gravity) {
    	mTitleTV.setGravity(gravity);
    }
    
    public void setHint(String hintStr){
    	mHintStr = hintStr;
        mTitleTV.setText(hintStr);
    }
    
    public String getHint() {
    	return mHintStr;
    }
    
    public void setDisplayFirstLabel(boolean display) {
        isDisplayFirstLabel = display;
    }
    
    
    public void setDropDownListData(List<MSpinnerBean> list){
    	mSelectedText = "";
    	mTitleTV.setText(mHintStr);
        mMSpinnerPopupWindow.setData(this.sortAddressBeanListToMSpinnerBeanList(list));
    }
    
    public List<MSpinnerBean> getDropDownListData(){
        return mMSpinnerPopupWindow.mPWList;
    }
    
    public void setEnabled(boolean enabled){
        mEnabled = enabled;
        if(!mEnabled){
            mArrowIV.setImageResource(R.drawable.drop_down_arrow_selected);
            this.closeMSpinner();
        }
    }
    
    public boolean isEnabled() {
        return mEnabled;
    }
    
    public void setDisplayItemInTitle(boolean display) {
    	isDisplayItemInTitle = display;
    }

    public void openMSpinner(View anchor){
        if(!mEnabled){
            return;
        }
        
        if(mMSpinnerState.equals(MSpinnerState.STATE_OPEN)){
            return;
        }
        
        mMSpinnerState = MSpinnerState.STATE_OPEN;
        this.mMSpinnerPopupWindow.showAsDropDown(anchor);
    }
    
    public void closeMSpinner(){
        if(mMSpinnerState.equals(MSpinnerState.STATE_CLOSE)){
            return;
        }
        mMSpinnerState = MSpinnerState.STATE_CLOSE;
        this.mMSpinnerPopupWindow.dismiss();
    }
    
    public void onDestroy(){
        mContentView = null;
        mTitleTV = null;
        mArrowIV = null;
        mOnMSpinnerItemClickListener = null;
        mSelectedMSpinnerBean = null;
        mMSpinnerPopupWindow.mAdapter = null;
        mMSpinnerPopupWindow.mListView = null;
        mMSpinnerPopupWindow.mPWList = null;
        mMSpinnerPopupWindow = null;
    }

    @Override
    public void onClick(View v) {
        if(v.equals(this)){
            if(mMSpinnerState.equals(MSpinnerState.STATE_OPEN)){
                closeMSpinner();
            }
            else{
                openMSpinner(v);
            }
        }
    }
    
    @Override
    public void onFocusChange(View v, boolean hasFocus)
    {
        if(v.equals(this)){
            if(hasFocus && mEnabled){
                mArrowIV.setImageResource(R.drawable.drop_down_arrow_selected);
            }
            else{
                mArrowIV.setImageResource(R.drawable.drop_down_arrow_selected);
            }
        }
    }
    
    public static class MSpinnerBean{
        /**
         * 是否显示首字母
         */
        public boolean flag;
        /**
         * 第一个字的首字母
         */
        public String dataStr;
        /**
         * 各个字首字母
         * 例如：中国人 ---> zgr;
         */
        public String firstPinYin;
        /**
         * 显示的数据
         */
        public String contentStr;
    }
    
    private List<MSpinnerBean> sortAddressBeanListToMSpinnerBeanList(List<MSpinnerBean> mspinnerBeanList){
        if(mspinnerBeanList != null && mspinnerBeanList.size()>0){
            for(MSpinnerBean bean : mspinnerBeanList){
                bean.firstPinYin = cn2FirstSpell(bean.contentStr);
                bean.dataStr = "" + bean.firstPinYin.charAt(0);
            }
            
            Collections.sort(mspinnerBeanList, new Comparator<MSpinnerBean>(){
                @Override
                public int compare(MSpinnerBean object1, MSpinnerBean object2)
                {
                    String firstPinYin1 = object1.firstPinYin;
                    String firstPinYin2 = object2.firstPinYin;
                    int size = firstPinYin1.length() < firstPinYin2.length() ? firstPinYin1.length() : firstPinYin2.length();
                    for(int i=0; i<size; i++){
                        if(firstPinYin1.charAt(i) > firstPinYin2.charAt(i)){
                            return 1;
                        }
                        else if(firstPinYin1.charAt(i) < firstPinYin2.charAt(i)){
                            return -1;
                        }
                    }
                    return 0;
                }
            });
            
            int size = mspinnerBeanList.size();
            for(int i=0; i<size; i++){
                MSpinnerBean mspinnerB = mspinnerBeanList.get(i);
                if(i == 0){
                    mspinnerB.flag = true;
                }
                else if(!mspinnerB.dataStr.equals(mspinnerBeanList.get(i-1).dataStr)){
                    mspinnerB.flag = true;
                }
                else{
                    mspinnerB.flag = false;
                }
            }
            
            return mspinnerBeanList;
        }
        return null;
    }
    
    /**
     * 获取汉字串拼音首字母，英文及特殊字符字符不变
     * @param chinese 汉字串
     * @return 汉语拼音首字母
     */
    private String cn2FirstSpell(String chinese)
    {
        StringBuffer pybf = new StringBuffer();
        char[] arr = chinese.toCharArray();
        HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
        defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        for (int i = 0; i < arr.length; i++)
        {
            Log.d("NEVER", String.valueOf(arr[i]));
            if (arr[i] > 128)
            {
                try
                {
                    String[] _t = PinyinHelper.toHanyuPinyinStringArray(arr[i], defaultFormat);
                    if (_t != null)
                    {
                        pybf.append(_t[0].charAt(0));
                    }
                } catch (BadHanyuPinyinOutputFormatCombination e)
                {
                    e.printStackTrace();
                }
            } else
            {
                pybf.append(arr[i]);
            }
        }
        return pybf.toString().toUpperCase().trim();
    }
    
    private class MSpinnerPopupWindow extends PopupWindow implements OnItemClickListener{
        private ListView mListView;
        private List<MSpinnerBean> mPWList;
        private MSpinnerPWListAdapter mAdapter;
        
        public MSpinnerPopupWindow(){
            this.setBackgroundDrawable(new BitmapDrawable());
            this.setFocusable(true);
            this.setOutsideTouchable(true);
            this.setClippingEnabled(false);
            
            LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View contentView = inflater.inflate(R.layout.mspinner_pw, null, false);
            this.setContentView(contentView);
            
            mListView = (ListView)contentView.findViewById(R.id.mspinner_pw_listview);
            mListView.setOnItemClickListener(this);
            mPWList = new ArrayList<MSpinnerBean>();
            
            mAdapter = new MSpinnerPWListAdapter(R.layout.mspinner_list_item, mPWList);
            mListView.setAdapter(mAdapter);
        }

        public void setData(List<MSpinnerBean> list){
            mPWList.clear();
            if(list != null){
                mPWList.addAll(list);
            }
            mAdapter.notifyDataSetChanged();
        }
        
        @Override
        public void showAsDropDown(View anchor) {
            if(mPWList==null || mPWList.size()==0){
                return;
            }
            
            Resources resources = mContext.getResources();
            //maxHeight : pw在屏幕中的最大显示高度
            int[] anchorLocation = new int[2];
            anchor.getLocationOnScreen(anchorLocation);
            DisplayMetrics dm = resources.getDisplayMetrics();
            int maxHeight = (dm.heightPixels - anchorLocation[1] - anchor.getHeight()) * 3 / 4;
            Log.d("CEXX", "CEXX ---> showAsDropDown ---> maxHeight : " + maxHeight);
            
            int itemHeight = resources.getDimensionPixelSize(R.dimen.mspinner_list_item_textsize)
                + resources.getDimensionPixelSize(R.dimen.mspinner_list_item_tv1_height);
            int h = itemHeight * mPWList.size()
                + mListView.getDividerHeight() * mPWList.size() 
                + mListView.getPaddingTop()
                + mListView.getPaddingBottom();
            Log.d("CEXX", "CEXX ---> showAsDropDown ---> h : " + h);
            
            //height : pw的显示高度
            int height = h < maxHeight ? h : maxHeight;
            Log.d("CEXX", "CEXX ---> showAsDropDown ---> height : " + height);
            
            this.setWidth(anchor.getWidth());
            this.setHeight(height);
            super.showAsDropDown(anchor);
        }

        @Override
        public void dismiss() {
            super.dismiss();
            if(mMSpinnerState == MSpinnerState.STATE_OPEN){
                closeMSpinner();
            }
        }

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            closeMSpinner();
            
            mSelectedMSpinnerBean = mPWList.get(position);
            mSelectedText = mSelectedMSpinnerBean.contentStr;
            
            if(isDisplayItemInTitle) {
            	mTitleTV.setText(mSelectedMSpinnerBean.contentStr);
            }
            
            if(mOnMSpinnerItemClickListener != null){
                mOnMSpinnerItemClickListener.onMSpinnerItemClick(MSpinner.this, position, mPWList.get(position));
            }
        }
    }

    private class MSpinnerPWListAdapter extends ArrayAdapter<MSpinnerBean>{
        private int mLayoutRes;
        private List<MSpinnerBean> mAdapterList;
        
        public MSpinnerPWListAdapter(int layoutRes, List<MSpinnerBean> list){
            super(mContext, layoutRes, list);
            mLayoutRes = layoutRes;
            mAdapterList = list;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder = null;
            if(convertView == null){
                LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(mLayoutRes, parent, false);
                viewHolder = new ViewHolder(convertView);
                convertView.setTag(viewHolder);
            }
            else{
                viewHolder = (ViewHolder)convertView.getTag();
            }
            
            MSpinnerBean bean = mAdapterList.get(position);
            viewHolder.getTvDataStr1().setText(bean.contentStr);
            if(isDisplayFirstLabel && bean.flag){
                viewHolder.getTvDataStr0().setVisibility(View.VISIBLE);
                viewHolder.getTvDataStr0().setText(bean.dataStr);
            }
            else{
                viewHolder.getTvDataStr0().setVisibility(View.GONE);
            }
            
            return convertView;
        }
        
        private class ViewHolder{
            private View mContentView;
            private TextView mTvDataStr0;
            private TextView mTvDataStr1;
            
            public ViewHolder(View contentView){
                mContentView = contentView;
            }
            
            public TextView getTvDataStr0(){
                if(mTvDataStr0 == null){
                    mTvDataStr0 = (TextView)mContentView.findViewById(R.id.mspinner_list_item_tv0);
                }
                return mTvDataStr0;
            }
            
            public TextView getTvDataStr1(){
                if(mTvDataStr1 == null){
                    mTvDataStr1 = (TextView)mContentView.findViewById(R.id.mspinner_list_item_tv1);
                }
                return mTvDataStr1;
            }
        }
    }
}









































